using Beaker.Common.Specs.SupportClasses;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Beaker.Common.Specs
{
	public sealed class MaybeExtensionSpecs
	{
		#region Select

		[TestMethod]
		public void DefaultValueIsReturnedWhenNullReferencePassed()
		{
			Maybe<FooBar> fooBar = new FooBar
			{
				SubFoo = new SubFoo()
			};

			var result = fooBar.Select(fb => fb.SubFoo).Select(sf => sf.Text, "Default");

			result.Should().Be("Default", because: "Text has no value and 'Default' was passes as default for Select");
		}

		[TestMethod]
		public void DefaultvalueIsReturnedWhenInputIsMaybeWithoutValue()
		{
			Maybe<FooBar> fooBar = new FooBar
			{
				SubFoo = new SubFoo()
			};

			var result = fooBar.Select(fb => fb.SubFoo).Select(sf => sf.OptionalNumber, 20);

			result.Should().Be(20, because: "OptionalNumber maybe has no value and '20' was passes as default for Select");
		}

		[TestMethod]
		public void DefaultValueIsReturnedWhenInputIsNullableWithNullValue()
		{
			FooBar fooBar = new FooBar
			{
				SubFoo = new SubFoo()
			};

			var result = Maybe.From(fooBar).Select(fb => fb.SubFoo).Select(sf => sf.NullableNumber, 20);

			result.Should().Be(20, because: "NullableNumber is null and '20' was passes as default for Select");
		}

		#endregion

		[TestMethod]
		public void ChainedMaybesWhereFirstIsNullShoudReturnFinalDefaultValue()
		{
			Maybe<FooBar> fooBar = new FooBar();

			var result = fooBar.Select(fb => fb.SubFoo).Select(sf => sf.NullableNumber, 20);

			result.Should().Be(20, because: "Chained maybe's where first is null, should return final default");
		}

		[TestMethod]
		public void ChainedMaybesWhereFirstHasNoValueShouldReturnMaybeWithoutValue()
		{
			Maybe<FooBar> fooBar = new FooBar();

			var result = fooBar.Select(fb => fb.SubFoo).Select(sf => sf.NullableNumber);

			result.Should().Be(new Maybe<int?>(), because: "Chained maybe's where first is null, should return maybe without value");
		}

	}
}